import Flutter
import UIKit
import AVFoundation

/**
 * iOS摄像头预览PlatformView
 * 
 * 这个类负责创建和管理iOS原生的摄像头预览视图
 */
class CameraPreviewView: NSObject, FlutterPlatformView {
    private var _view: UIView
    private var previewLayer: AVCaptureVideoPreviewLayer?
    
    init(
        frame: CGRect,
        viewIdentifier viewId: Int64,
        arguments args: Any?,
        binaryMessenger messenger: FlutterBinaryMessenger?
    ) {
        print("CameraPreviewView: 初始化开始，frame: \(frame), viewId: \(viewId)")
        _view = UIView(frame: frame)
        super.init()
        
        // 设置背景色为黑色
        _view.backgroundColor = UIColor.black
        print("CameraPreviewView: 视图背景色设置为黑色")
        
        // 获取摄像头管理器并设置预览
        print("CameraPreviewView: 准备设置摄像头预览")
        setupCameraPreview()
        
        // 应用创建参数
        if let arguments = args as? [String: Any] {
            print("CameraPreviewView: 应用创建参数: \(arguments)")
            applyCreationParams(arguments)
        } else {
            print("CameraPreviewView: 没有创建参数")
        }
        
        print("CameraPreviewView: 初始化完成")
    }
    
    func view() -> UIView {
        return _view
    }
    
    // 视图布局更新时调整预览层大小
    private func updatePreviewLayerFrame() {
        guard let previewLayer = self.previewLayer else { return }
        
        DispatchQueue.main.async { [weak self] in
            guard let self = self else { return }
            
            var frame = self._view.bounds
            if frame.width > 0 && frame.height > 0 {
                previewLayer.frame = frame
                print("CameraPreviewView: 更新预览层frame: \(frame)")
            }
        }
    }
    
    private func setupCameraPreview() {
        print("CameraPreviewView: setupCameraPreview() 开始")
        
        // 尝试获取当前的摄像头管理器和预览层
        tryAttachPreviewLayer()
        
        // 监听视图大小变化
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(orientationChanged),
            name: UIDevice.orientationDidChangeNotification,
            object: nil
        )
        
        // 监听摄像头初始化完成通知
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(cameraInitialized),
            name: NSNotification.Name("CameraInitialized"),
            object: nil
        )
        
        // 如果预览层还没有附加，定时重试
        if previewLayer == nil {
            print("CameraPreviewView: 预览层未附加，启动重试定时器")
            startRetryTimer()
        } else {
            print("CameraPreviewView: 预览层已成功附加")
        }
    }
    
    private func tryAttachPreviewLayer() {
        print("CameraPreviewView: 尝试附加预览层")
        
        guard let cameraManager = MultiCameraPlugin.getCurrentCameraManager() else {
            print("CameraPreviewView: 无法获取摄像头管理器")
            return
        }
        
        print("CameraPreviewView: 摄像头管理器已获取")
        
        guard let newPreviewLayer = cameraManager.getPreviewLayer() else {
            print("CameraPreviewView: 无法获取预览层")
            return
        }
        
        print("CameraPreviewView: 预览层已获取，开始附加")
        
        // 如果已有预览层，先移除
        if let existingLayer = previewLayer {
            print("CameraPreviewView: 移除现有预览层")
            existingLayer.removeFromSuperlayer()
        }
        
        self.previewLayer = newPreviewLayer
        
        // 确保在主线程执行UI操作
        DispatchQueue.main.async { [weak self] in
            guard let self = self else { return }
            
            // 如果视图大小为0，设置一个默认大小
            var frame = self._view.bounds
            if frame.width == 0 || frame.height == 0 {
                frame = CGRect(x: 0, y: 0, width: 300, height: 400)
                print("CameraPreviewView: 视图bounds为空，使用默认大小: \(frame)")
            }
            
            // 配置预览层
            newPreviewLayer.frame = frame
            newPreviewLayer.videoGravity = .resizeAspectFill
            
            print("CameraPreviewView: 配置预览层 frame: \(frame)")
            
            // 添加到视图
            self._view.layer.addSublayer(newPreviewLayer)
            print("CameraPreviewView: 预览层已添加到视图")
            
            // 更新视图大小以匹配预览层
            if self._view.bounds.width == 0 || self._view.bounds.height == 0 {
                self._view.frame = frame
                print("CameraPreviewView: 更新视图frame: \(frame)")
            }
        }
    }
    
    private func startRetryTimer() {
        // 每500ms重试一次，最多重试20次（10秒）
        var retryCount = 0
        let maxRetries = 20
        
        Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { [weak self] timer in
            guard let self = self else {
                timer.invalidate()
                return
            }
            
            retryCount += 1
            
            // 尝试附加预览层
            self.tryAttachPreviewLayer()
            
            // 如果成功附加或超过最大重试次数，停止定时器
            if self.previewLayer != nil || retryCount >= maxRetries {
                timer.invalidate()
            }
        }
    }
    
    @objc private func cameraInitialized() {
        // 收到摄像头初始化完成通知，尝试附加预览层
        DispatchQueue.main.async { [weak self] in
            self?.tryAttachPreviewLayer()
        }
    }
    
    @objc private func orientationChanged() {
        // 更新预览层大小
        print("CameraPreviewView: 设备方向改变，更新预览层")
        updatePreviewLayerFrame()
    }
    
    private func applyCreationParams(_ params: [String: Any]) {
        // 应用Flutter传递的配置参数
        if let width = params["width"] as? Double,
           let height = params["height"] as? Double {
            // 设置固定大小
            _view.frame.size = CGSize(width: width, height: height)
        }
        
        if let isCircular = params["isCircular"] as? Bool, isCircular {
            // 设置圆形遮罩
            _view.layer.cornerRadius = min(_view.frame.width, _view.frame.height) / 2
            _view.layer.masksToBounds = true
        } else if let borderRadius = params["borderRadius"] as? Double, borderRadius > 0 {
            // 设置圆角
            _view.layer.cornerRadius = CGFloat(borderRadius)
            _view.layer.masksToBounds = true
        }
        
        // 注释掉边框设置，避免与Flutter层的边框重复
        // Flutter层会通过Container的decoration来统一处理边框
        // 这样可以与FlutterCamera实现保持一致，只有外层边框
        /*
        if let showBorder = params["showBorder"] as? Bool, showBorder {
            if let borderColor = params["borderColor"] as? Int64 {
                _view.layer.borderColor = UIColor(rgb: borderColor).cgColor
            } else {
                _view.layer.borderColor = UIColor.white.cgColor
            }
            
            if let borderWidth = params["borderWidth"] as? Double {
                _view.layer.borderWidth = CGFloat(borderWidth)
            } else {
                _view.layer.borderWidth = 1.0
            }
        }
        */
    }
    
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
}

/**
 * PlatformView工厂类
 */
class CameraPreviewViewFactory: NSObject, FlutterPlatformViewFactory {
    private var messenger: FlutterBinaryMessenger
    
    init(messenger: FlutterBinaryMessenger) {
        self.messenger = messenger
        super.init()
    }
    
    func create(
        withFrame frame: CGRect,
        viewIdentifier viewId: Int64,
        arguments args: Any?
    ) -> FlutterPlatformView {
        print("CameraPreviewViewFactory: create() 被调用")
        print("CameraPreviewViewFactory: frame = \(frame)")
        print("CameraPreviewViewFactory: viewId = \(viewId)")
        print("CameraPreviewViewFactory: arguments = \(String(describing: args))")
        
        let previewView = CameraPreviewView(
            frame: frame,
            viewIdentifier: viewId,
            arguments: args,
            binaryMessenger: messenger
        )
        
        print("CameraPreviewViewFactory: CameraPreviewView 创建完成")
        return previewView
    }
    
    func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol {
        return FlutterStandardMessageCodec.sharedInstance()
    }
}

// MARK: - UIColor Extension

extension UIColor {
    convenience init(rgb: Int64) {
        let red = CGFloat((rgb >> 16) & 0xFF) / 255.0
        let green = CGFloat((rgb >> 8) & 0xFF) / 255.0
        let blue = CGFloat(rgb & 0xFF) / 255.0
        let alpha = CGFloat((rgb >> 24) & 0xFF) / 255.0
        
        self.init(red: red, green: green, blue: blue, alpha: alpha == 0 ? 1.0 : alpha)
    }
}
